home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / tuner / tuner.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-06  |  40.9 KB  |  1,440 lines

  1. /*
  2. %    TUNER . C
  3. %
  4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5.  
  6. This software is copyright (C) by the Lawrence Berkeley Laboratory.
  7. Permission is granted to reproduce this software for non-commercial
  8. purposes provided that this notice is left intact.
  9.  
  10. It is acknowledged that the U.S. Government has rights to this software
  11. under Contract DE-AC03-765F00098 between the U.S.  Department of Energy
  12. and the University of California.
  13.  
  14. This software is provided as a professional and academic contribution
  15. for joint exchange. Thus, it is experimental, and is provided ``as is'',
  16. with no warranties of any kind whatsoever, no support, no promise of
  17. updates, or printed documentation. By using this software, you
  18. acknowledge that the Lawrence Berkeley Laboratory and Regents of the
  19. University of California shall have no liability with respect to the
  20. infringement of other copyrights by any part of this software.
  21.  
  22. For further information about this notice, contact William Johnston,
  23. Bld. 50B, Rm. 2239, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  24. (wejohnston@lbl.gov)
  25.  
  26. For further information about this software, contact:
  27.     Jin Guojun
  28.     Bld. 50B, Rm. 2275, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  29.     g_jin@lbl.gov
  30.  
  31. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  32. %
  33. %    The ELASTIC TUNER main routine Tuner(), editor routines.
  34. %
  35. %    There are 2 places (case fButton & Button3) re-using histogram().
  36. %    Of course, if there are more memory in system, this time can be saved.
  37. %    Two versions are set up here:
  38. %        direct color mapping and quantizing mode.
  39. %
  40. % compile:    -DDIRECT will generate fast version, but will not share
  41. %        color map with other images runing with it. And this fast
  42. %        version is mainly used for image viewing, not editing.
  43. %
  44. % Author:    Jin Guojun - Lawrence Berkeley Laboratory    4/1/91
  45. */
  46.  
  47. #include "tuner.h"
  48. #include "info_any.c"
  49.  
  50. #define    Dpy1    Monitor[1].dpy
  51. #define    Put_Image(img)    XPutImage(img->dpy,    \
  52.         img->refresh_pixmap ? img->refresh_pixmap : img->win,    \
  53.         img->gc, img->image, 0, 0, 0, 0, img->width, img->height);
  54.  
  55. bool    clickon, moved,    /* for pointer motion    */
  56.     newmap, cquire, cca, verbose, quant;
  57. int    ncolors=NCOLOR, BackGD, OsameI, num_images,
  58.     x_regions=2, y_regions=2,
  59.     fontWidth, fontHeight;    /* public font size */
  60. LKT    *lkt;
  61. MType    fsize;
  62. Image    **pic;
  63. Cursor    arrow;
  64. EditorSpace    I_ED;
  65. Image    cmn_hd;
  66. static    char    lbuf[128], *EmptySheet="empty frame";
  67.  
  68.  
  69. static    int    MBUTTON_ACTION[3][3]={
  70.     CONTROL_EVENT,    MAGNIFY_EVENT,    MENU1,
  71.     HISTO_EVENT,    MAGNIFY_SHIFT,    MENU2,
  72.     MOVIE_EVENT,    UNMAGNIFY,    MENU3
  73.     };
  74.  
  75. GetImageBufNSize(img)
  76. register Image    *img;
  77. {
  78. register int    size = img->width * img->height;
  79.     img->cnvt = img->data + (img->color_dpy ? 0 : img->fn * size);
  80. return    size;
  81. }
  82.  
  83. #ifdef    C_TUNER
  84.  
  85. #define    ImageBackup(img)    if (img->refresh_pixmap)    \
  86.     XCopyArea(img->dpy, img->refresh_pixmap, img->win, img->gc,    \
  87.         0, 0, img->width, img->height, 0, 0);
  88.  
  89. Tuner(imgp, max_images, active)
  90. Image    **imgp;
  91. bool    *active;
  92. {
  93. register MType    i;
  94. Image    *imginfo, *img;
  95. int    sb;
  96. XEvent        event;    /* p16 Xlib.h    */
  97. XExposeEvent    *expose;/* p11 Xlib.h    */
  98. XCrossingEvent    *xcrossing;
  99. expose = (XExposeEvent *) &event;
  100. xcrossing = (XCrossingEvent *) &event;
  101.  
  102. for (i=0; i<num_images; i++)
  103.     imgp[i]->event = &event;
  104. for (i=0; i<num_images; i++)
  105.     if (imgp[i]->active)    break;
  106. if (i >= num_images)
  107.     i = 0;
  108. imginfo = img = imgp[i];
  109. PanelMessage(FButton, img->name, 0, 0, 0);
  110. if (img->marray)
  111.     memcpy(&img->mmm, img->marray, sizeof(img->mmm));
  112. img->cnvt = img->data;
  113.  
  114. if (*active<0)    XMapWindow(Epanel->dpy, Epanel->win);
  115.  
  116. #else    Gray_Scale_tuner
  117.  
  118.  
  119. main(argc, argv)
  120. int    argc;
  121. char    **argv;
  122. {
  123. register int    i;
  124. int    VCTolerance=0, max_images=12, ela_scale=6, nf, xy_ext=0;
  125. float    thdscale=0.00500001;
  126. char    **fl;
  127.  
  128. format_init(&cmn_hd, IMAGE_INIT_TYPE, HIPS, HIPS, *argv, "S20-1");
  129. if ((nf=parse_argus(&fl, argc, argv, arg_list,
  130. #ifdef    DIRECT
  131.     &VCTolerance,
  132. #else
  133.     &ncolors,
  134. #endif
  135.     &cca, &cquire,
  136.     &DEBUGANY, &DEBUGANY,
  137.     &display_name, &display_name,
  138.     &thdscale, &ela_scale,
  139.     &max_images,
  140.     &newmap, &precision,
  141.     &start_fast, &verbose,
  142.     &xy_ext, &x_regions,
  143.     &x_regions, &y_regions)) < 0)    exit(nf);
  144.  
  145. if (!xy_ext)    y_regions = x_regions;
  146. if (!VCTolerance)
  147.     VCTolerance = (ncolors>>ToleranceFactor)+16;
  148. if (precision<128)    /* small value may get more close color */
  149.     precision = 256;    /* but easy to failure */
  150.  
  151.     /* Open the display & set defaults */
  152. if ((Dpy1 = XOpenDisplay(display_name)) == NULL)
  153.     syserr("Can't open display '%s'", XDisplayName(display_name));
  154. if (!display_name)    display_name = XDisplayName(display_name);
  155. i = strlen(display_name);
  156. msg("display = %s\n", display_name);
  157.  
  158. if (display_name[i-1] != '0') {    /* number 0 {48H in ASCII} */
  159. char    str[64];
  160.     strcpy(str, display_name);
  161.     str[i-1] = '0';
  162.     if ((Dpy = XOpenDisplay(str)) == NULL)
  163.         syserr("Can't open display '%s'", str);
  164.     msg("display = %s\n", str);
  165. }
  166. else    Dpy = Dpy1;
  167. Set_Monitor(NULL, Dpy, Dpy1, NULL);
  168.  
  169. if (XDisplayPlanes(Dpy1, Monitor[1].screen) == 1)
  170.     mesg("control panel is on a monochrome screen\n");
  171.  
  172. dgt = (int*) zalloc(MaxColors, sizeof(*dgt), "dgt");
  173. if (Monitor[0].dpy_depth < 24)
  174.     GetVctEntry(Dpy, Screen, Monitor[0].cmap,
  175.         start_fast<2 && Monitor[1].dpy_depth>1 ||
  176.         Dpy==Dpy1 && Monitor[1].dpy_depth==1);
  177. else    VCTEntry = 1;
  178.  
  179. #ifdef    DIRECT
  180. if (VCTEntry<1 || ncolors+VCTEntry-MaxColors > VCTolerance)
  181.     newmap--;
  182. CreateCLT(graylevel, ncolors, DoAll, 0, False, &histinfo);
  183. Monitor[0].cmap = SetColormap(&Monitor[0], graylevel, ncolors, &newmap,
  184.     VCTEntry);
  185. #else
  186. if (VCTEntry < 1)    newmap--;
  187. else if (ncolors+VCTEntry-MaxColors > VCTolerance)
  188.     ncolors >>= 1;
  189. CreateCLT(graylevel, ncolors, DoAll, 0, True, &histinfo);
  190. Monitor[0].cmap = SetColormap(&Monitor[0], graylevel, &ncolors, &newmap, 0);
  191. #endif
  192. if (Dpy == Dpy1)
  193.     Monitor[1].cmap = Monitor[0].cmap;
  194. if (max_images<1 || max_images>256)
  195.     max_images = 64;
  196.  
  197. cmn_hd.dpy = Dpy;
  198. cmn_hd.dpy_depth = Monitor[0].dpy_depth;
  199. CreateTuner(&cmn_hd, ela_scale, darkGray, True);
  200.  
  201. pic = (Image**) zalloc(max_images, sizeof(**pic), "pic");
  202.  
  203.     /* if stdin is ready, load image. */
  204. i = True;
  205. io_test(fileno(stdin), i=iset);
  206. if (i)    LoadImage(stdin, pic, fname);
  207. else  while (i < nf)    {
  208.     if (!(freopen(fname=fl[i], "rb", stdin)) )
  209.         syserr("input %s", fl[i]);
  210.     LoadImage(stdin, pic+i++, fname);
  211. }
  212. Tuner(pic, max_images);        /* analyse images */
  213. }    /* End of Main    */
  214.  
  215.  
  216. Tuner(imgp, max_images)
  217. Image    **imgp;
  218. {
  219. Image    *img,    /* only set by load, map, enter.
  220.             So, it always represents the current image */
  221.     *imginfo=NULL;    /* temp image pointer, parameter window    */
  222. int    sb;
  223. XEvent        event;    /* p16 Xlib.h    */
  224. XExposeEvent    *expose;/* p11 Xlib.h    */
  225. XCrossingEvent    *xcrossing;
  226. register MType    i=0;
  227.  
  228. while (img=imgp[i]) {
  229.     img->cnvt = img->data;    i++;
  230.     img->event = &event;
  231. }
  232. if (num_images = i)
  233.     (img=imgp[--i])->active = True;
  234. XSelectInput(histinfo.his->dpy, histinfo.his->win, I_Mask);
  235. expose = (XExposeEvent *) & event;
  236. xcrossing = (XCrossingEvent *) & event;
  237.  
  238. I_ED.copy = (Image*) nzalloc(sizeof(*I_ED.copy), 1, "I_copy");
  239.  
  240. #endif     C_TUNER
  241.  
  242.  
  243. /*    public tuner()    */
  244.  
  245. #ifndef    HISTO_BACKGROUND
  246. #define    HISTO_BACKGROUND    lightGray
  247. #endif
  248.  
  249. while (True) {    /* the loop to maintain the images.    PUBLIC entry */
  250. #ifdef    _DEBUG_
  251. #include <time.h>
  252. time_t    t0, t1;
  253. #endif
  254.  
  255. int    mevent, y0, new_colors=ncolors, ps=1;
  256. Window    wp;    /* long, defined in X.h */
  257. KeySym    keysym;
  258. XComposeStatus    stat;
  259.     if (event.type != MotionNotify) {
  260.         sprintf(lbuf,
  261.         "(q)uit   {%d}%-8d BUTTON => [1]Ctrl   [2]Hist   [3]Movie",
  262.         histinfo.scale, img?img->mmm.maxcnt:0);
  263.         DispInfo(Epanel, 0, lbuf, white1);
  264.     }
  265.     if (Dpy == Dpy1)
  266.         XNextEvent(Dpy, &event);/* waiting for event */
  267.     else    {
  268.         i = 0;
  269.         while (!XEventsQueued(Dpy, QueuedAfterFlush) &&
  270.             !(i=XEventsQueued(Dpy1, QueuedAfterFlush)));
  271.         if (i)    XNextEvent(Dpy1, &event);
  272.         else    XNextEvent(Dpy, &event);
  273.     }
  274.  
  275.     wp = event.xany.window;
  276.     switch ((int) event.type) {
  277.     case Expose:
  278.         if ((i=WhichImage(wp, imgp, num_images))>=0)
  279.             imginfo = imgp[i];
  280.         Exposure_handler(expose, imginfo);
  281.     XFlush(Dpy);
  282.     break;
  283.  
  284.     case ButtonPress:
  285.         i = event.xbutton.button;
  286.         mevent = event.xbutton.state & (ShiftMask | ControlMask);
  287.         if (mevent>2)    mevent = 2;
  288.         mevent = MBUTTON_ACTION[i-Button1][mevent];
  289.         if (OnButton(FButton, &event.xbutton) > 0 &&
  290.         (i=FileAccess(imgp, max_images, num_images))) {
  291.             if (img)    img->active = False;
  292.             if (i == EOF)    {    /* SUCCESSful LOADing    */
  293.                 img = imgp[num_images];
  294.                 img->event = &event;
  295.                 num_images++;
  296.             }
  297.             else    img = imgp[i];
  298.             img->active = True;
  299. #    ifdef    DIRECT
  300.             frmchange++;
  301. #    endif
  302.             img->cnvt = img->data;
  303.             break;
  304.         }
  305.         else if (mevent==MENU2) {
  306.         switch (i=PopingMenu(paramenu, numpara, NULL)) {
  307.         case MENU2_FITSType:    {
  308. #ifdef    FITS_IMAGE
  309.         extern    int    FTy;
  310.             sprintf(lbuf, "[%c] Unix Vax Pc T->unix_vax", FTy);
  311.             Get_Note_Input(lbuf, sizeof(lbuf), 7, "TYPE ", Yellow, 0);
  312.             FTy = lbuf[0];
  313.             if (FTy != 'u' && FTy != 'v' && FTy != 'p' && FTy != 't')
  314.                 FTy = 'u';
  315. #endif
  316.         }    break;
  317.         case MENU2_ETAScale:
  318.             if (!img)    break;
  319.             sprintf(lbuf, "\n\nlevel = %d (Max : 65)", img->scale);
  320.             Get_Note_Input(lbuf, sizeof(lbuf), 8, "scale ", Yellow, Yes);
  321.             img->scale = i = atoi(lbuf);
  322.             ChangeSliderScale(ESlider, i, slider==ESlider);
  323.             break;
  324.         case MENU2_ITPRange:
  325.             sprintf(lbuf, "level = %d, Max level = 8", x_regions);
  326.             Get_Note_Input(lbuf, sizeof(lbuf), 8, "level ", Green, 0);
  327.             i = atoi(lbuf);
  328.             if (i<2 || i>MAX_ITP_LEVEL)    i = 2;
  329.             x_regions = y_regions = i;
  330.             break;
  331.         case MENU2_RGBScale:
  332.             sprintf(lbuf, "R-G-B = %d %d %d",
  333.                 RED_to_GRAY, GREEN_to_GRAY, BLUE_to_GRAY);
  334.             Get_Note_Input(lbuf, sizeof(lbuf), 0, "R.G.B factor ", Green, 0);
  335.             sscanf(lbuf, "%d %d %d",
  336.                 &RED_to_GRAY, &GREEN_to_GRAY, &BLUE_to_GRAY);
  337.             break;
  338.         case MENU2_BackGD:
  339.             sprintf(lbuf, "Background = %d", BackGD);
  340.             Get_Note_Input(lbuf, sizeof(lbuf), 0, "new back ground ", Green, 0);
  341.             BackGD = atoi(lbuf);
  342.             break;
  343.         default:    XBell(Epanel->dpy, 10);
  344.         }
  345.         HidingPanel(NoteWin);
  346.         break;
  347.         }
  348.         else if (mevent==MENU3)    {
  349.         char    errbuf[128];
  350.         switch(i = PopingMenu(filemenu, numcomd, NULL))    {
  351.         case MENU3_BLKFrm:    {
  352.             int    w, h;
  353.             strcpy(lbuf, "new frame size:\n width height");
  354.             Get_Note_Input(lbuf, sizeof(lbuf), 0, NULL, Green, 0);
  355.             sscanf(lbuf, "%d %d", &w, &h);
  356.             if (w < 64 || h < 64)
  357.                 WaitOk(AbortButt, "size to small", 0);
  358.             else {
  359.             register int    chan = cmn_hd.color_dpy ? 3 : 1;
  360.             register byte    *clean;
  361.                 if (num_images >= max_images)
  362.                     break;
  363. #    ifdef    C_TUNER
  364.                 if (chan==3) {
  365.                 int    icn_f;
  366.                     img = imgp[num_images] = (Image*)zalloc(1,
  367.                         sizeof(image_information), EmptySheet);
  368.                     init_img_info(img, Dpy, RLE, cmn_hd.color_dpy);
  369.                     img->active = img->pixmap_failed = 1;
  370.                     init_img_flag(img);
  371.                     img->width = w,    img->height = h;
  372.                     img->channels = img->dpy_channels = chan;
  373.                     img->name = EmptySheet;
  374.                     find_appropriate_visual(img);/* may copy from parent */
  375.                     BuildColorImage(img, NULL, NULL, &icn_f);
  376.                 } else
  377. #    endif
  378.                 {       imgp[num_images] = NULL;
  379.                     BuildImage(imgp+num_images, "tmp", w, h,
  380.                         1, NULL, chan==1 ? HIPS : RLE, True);
  381.                     img = imgp[num_images];
  382.                     img->colormap = Monitor[0].cmap;
  383.                     img->channels = img->dpy_channels = chan;
  384.                 }
  385.                 num_images++;
  386.                 img->color_form = chan==3 ? CFM_ILL : CFM_SCF;
  387.                 SetImageEvent(img, &event);
  388.                 img->data = clean = nzalloc(w*h, chan, "blk-data");
  389.                 if (chan > 1)
  390.                     img->scan_data = nzalloc(w*h, chan, "blk-scan");
  391.                 for (chan*=w*h; chan--;)
  392.                     clean[chan] = -1;
  393.             }
  394.         }    break;
  395.         case MENU3_CDIR:
  396.             sprintf(lbuf, "%s\nChange directory to",
  397.                 getcwd(NULL, 256));
  398.             Get_Note_Input(lbuf, sizeof(lbuf), 0, NULL, Green, 0);
  399.             if (chdir(lbuf)) {
  400.                 sprintf(errbuf, "wrong directory:\n  %s", lbuf);
  401.                 WaitOk(NULL, errbuf, 0);
  402.             }
  403.             break;
  404. #    ifdef    C_TUNER
  405.         case MENU3_MAP123:
  406.             OsameI = YesOrNo("Map 1 to 3 channels for input ?", 0);
  407.             break;
  408.         case MENU3_LDFrm:
  409.             sprintf(lbuf, "frame = %d", img->fn);
  410.             Get_Note_Input(lbuf, sizeof(lbuf), 0, NULL, 0, 0);
  411.             img->fn = atoi(lbuf);
  412.             break;
  413. #    endif
  414.         case MENU3_OType:
  415.             sprintf(lbuf, "OUTPUT TYPE : %s\nHIPS, RAS, RLE",
  416.                 ITypeName[img->o_type]);
  417.             Get_Note_Input(lbuf, sizeof(lbuf), 0, NULL, 0, 0);
  418.             if ((i=available_type(lbuf)) > 0)
  419.                 img->o_type = i;
  420.             break;
  421.         case MENU3_QUIT:    goto    MEXIT;
  422.         }
  423.         HidingPanel(NoteWin);
  424.         break;
  425.         }
  426.         else if (!img)
  427.         break;
  428.  
  429.         if ((wp==img->win || wp==histinfo.his->win) &&
  430.         (mevent==CONTROL_EVENT || mevent==MOVIE_EVENT))    {
  431.         if (wp==img->win) {
  432.             XDefineCursor(img->dpy, wp, 0);
  433.             imginfo = img;
  434.         }
  435.         else{    imginfo = histinfo.his;
  436.             imginfo->mmm = img->mmm;
  437.         }
  438.         y0 = SetParameterWin(imginfo, &event, fontHeight, i==Button3);
  439.         }
  440.         switch (mevent) {
  441.         case CONTROL_EVENT:    /* on Botton1 */
  442.         if (i=Button1_On(&event.xbutton, &sb))
  443.         switch (i)    {
  444.             case OnETASlider:
  445.             clickon=ELALINFO;    break;
  446.             case OnClipSlider:
  447.             clickon=CLIPINFO;    break;
  448.             case OnQuanSlider:
  449.             clickon=QUANINFO;    break;
  450.             case OnZcntButton:
  451.             cntz = ButtonState(ZButton);    break;
  452. #    ifndef    DIRECT
  453.             case OnQuanButton:
  454.             quant = ButtonState(QButton);
  455.             if (!quant)    {
  456.                 moved = new_colors = ncolors;
  457.                 CreateCLT(graylevel, ncolors, DoAll, quant, 1, &histinfo);
  458.                 SetColormap(&Monitor[0], graylevel, &new_colors, &newmap, !quant);
  459.             }
  460. #    endif
  461.             break;
  462.             case OnFrameButton:
  463. #ifdef    C_TUNER
  464.             img->fn = ButtonState(fButton);
  465.             i = img->fn % 3;
  466.             img->mmm.min = img->marray[img->fn%img->channels].min;
  467.             img->mmm.max = img->marray[img->fn%img->channels].max;
  468.             img->curve = ButtonState(EButton) = cer[i].curve;
  469.             if (img->curve != ETALinear)
  470.                 SetSBarPos(ESlider, img->curve ?
  471.                 cer[i].bgrd : cer[i].fgrd, 1);
  472.             img->linearlow = cer[i].lower;
  473.             img->linearup = cer[i].upper;
  474.             ChangeSlider(img, &slider, ESlider, LSlider, heqButt, EButton);
  475.             PressButtonState(heqButt) = RESETSTATE;
  476.             DrawPressButton(heqButt);
  477. #else
  478.             if (img->frames>1) switch(ButtonState(fButton))    {
  479.             case NumFRAME:
  480.                 sprintf(lbuf, "Input frame# <= %d", img->frames);
  481.                 i = (strlen(lbuf)+2) * Epanel->font_w;
  482.                 DispInfo(Epanel, 0, lbuf, white1);
  483.                 lbuf[0] = 0;    /* clean buf */
  484.                 TextLine(fButton, lbuf, sizeof(lbuf), i,
  485.                     Exposure_handler, imgp, num_images);
  486.                 i = atoi(lbuf);
  487.                 if (i>0 && i<=img->frames)    img->fn = i-1;
  488.                 break;
  489.             case PrevFRAME:    if (img->fn)    img->fn--;
  490.                 break;
  491.             case NextFRAME:    if (img->fn<img->frames-1)
  492.                         img->fn++;
  493.             }
  494.             ButtonState(fButton)=RESETSTATE;
  495.             sprintf(lbuf, fb_format, img->fn+1, img->frames);
  496.             if (moved=strcmp(lbuf, fButton->bname[PosFRAME])) {
  497.                 fsize = GetImageBufNSize(img);
  498.                 i = histogram(img->cnvt, fsize, histinfo.histp, 0);
  499.                 img->mmm.min = img->marray[img->fn].min;
  500.                 img->mmm.max = img->marray[img->fn].max;
  501.                 if (!img->setscale)
  502.                     img->mmm.maxcnt = i,
  503.                     ResetORange(img);
  504.                 strcpy(fButton->bname[PosFRAME], lbuf);
  505. #    ifdef    DIRECT
  506.                 frmchange++;
  507. #    endif
  508.             }
  509.             DrawButton(fButton);
  510. #    endif
  511.             break;
  512.             case OnDataButton:    /* update image->data */
  513.             Update_ImageData(img, lbuf);
  514.             case OnInterpolate:
  515.             cer[0].intp = i==OnInterpolate;
  516.             if (cer[0].intp && img->color_form == CFM_SCF)    {
  517.                 ButtonState(Interpolate) = RESETSTATE;
  518.                 break;
  519.             }
  520.             Find_min_max(img, histinfo.histp, img->cnvt, Yes, True);
  521.             case OnETAButton:
  522.             img->curve = ButtonState(EButton);
  523. #    ifdef    C_TUNER
  524.             i = img->fn % 3;
  525.             cer[i].curve = img->curve;
  526.             img->bgrd = cer[i].bgrd;
  527.             img->fgrd = cer[i].fgrd;
  528.             img->linearlow = cer[i].lower;
  529.             img->linearup  = cer[i].upper;
  530. #    endif
  531.             ChangeSlider(img, &slider, ESlider, LSlider, heqButt, EButton);
  532.             moved++;
  533.             break;
  534.  
  535.             case OnHistButton:
  536.             Histo_Setting(img, lbuf);
  537.             break;
  538.             case OnResetButton:
  539.             {
  540.             moved++;
  541.             ResetORange(img);
  542.             }    break;
  543.             case OnRefresh:
  544.             moved++;
  545.             img->curve &= ~ETAHistoEq;
  546.             break;
  547.             case OnHEQButton:
  548.             moved = img->curve |= ETAHistoEq;
  549.             break;
  550.             default:    /* a lazy job ! should do something better */
  551.             if ((i=WhichImage(wp, imgp, num_images))>=0 &&
  552.                 img->parts && (sb=OnScrollBar(img->parts,
  553.                 &event.xbutton)))
  554.                 clickon = MOVESCROLLBAR;
  555.             else if (wp != Epanel->win)    {
  556. #    ifdef    C_TUNER
  557.                 if (wp != histinfo.his->win)
  558.                 ColorImageInfo(img, !y0);
  559.                 else
  560. #    endif
  561.                 ParameterWin(imginfo, &histinfo,
  562.                     event.xbutton.x, event.xbutton.y,
  563.                     y0, wp==histinfo.his->win),
  564.                 clickon = IMAGEINFO;
  565.             }
  566.         } break;    /* end of Button1 */
  567.         case HISTO_EVENT:    /* on Button2    */
  568.         if (img)    Map_HistoWin(img);
  569.         break;
  570.  
  571.         case MOVIE_EVENT:    /* on Button3    */
  572.         XBell(Dpy, 0);
  573. #    ifdef    _DEBUG_
  574.         time(&t0);
  575. #    endif
  576. #    ifndef    C_TUNER
  577.         if(OnButton(fButton, &event.xbutton) > 0 &&
  578.         event.xbutton.window == Epanel->win)    {
  579.         char    val[8];
  580.         DispInfo(Epanel, 0, "s => stop", Yellow);
  581.         if (img->curve & ETAHistoEq)    strcpy(lbuf, "Histo Equalization");
  582.         else if(img->curve<ETALinear)    strcpy(lbuf, "Elastic");
  583.         else    strcpy(lbuf, "Linear");
  584.         DispInfo(Epanel, 100, lbuf, Yellow);
  585.         while(1){
  586.             if (ButtonState(fButton) == PrevFRAME)
  587.                 if (img->fn)    img->fn--;
  588.                 else    break;
  589.             else if(img->fn<img->frames-1)    img->fn++;
  590.                 else    break;
  591.             if (XCheckMaskEvent(Dpy, KeyPressMask, &event))    {
  592.                 XLookupString(&event, lbuf, sizeof(lbuf),
  593.                     &keysym, &stat);
  594.                 if (lbuf[0] == 's')    break;
  595.             }
  596.             GetImageBufNSize(img);
  597.             img->mmm.min = img->marray[img->fn].min;
  598.             img->mmm.max = img->marray[img->fn].max;
  599.             if (!img->setscale)
  600.                 img->mmm.maxcnt = img->marray[img->fn].maxcnt,
  601.                 ResetORange(img);
  602.             new_curve(lkt, &histinfo, &img->mmm, img->curve, 0,
  603.                 img, fsize);
  604. #    ifdef    DIRECT
  605.             frmchange++;
  606.             MapColor(img, img->cnvt, fsize,
  607.                 graylevel, MAX(VCTEntry, img->mmm.min));
  608. #    else
  609.             MapColor(img, img->cnvt, fsize);
  610. #    endif
  611.             if (histinfo.map){
  612.                 histogram(img->cnvt, fsize, histinfo.histp, 0);
  613.                 HistoHandle(img, &histinfo, HISTO_BACKGROUND);
  614.                 sprintf(lbuf, "%d", img->mmm.maxcnt);
  615.                 DispInfo(Epanel, 240, lbuf, Green);
  616.                 SetShowFramePos(img, fButton, 0);
  617.             }
  618.         }
  619.         SetShowFramePos(img, fButton, True);
  620.         if (img->sub_img)
  621.             DrawCrop(img, 0, 1);
  622. #    ifdef    _DEBUG_
  623.         time(&t1);
  624.         message("time = %d\n", t1-t0);
  625. #    endif
  626.         }
  627.         else
  628. #    endif
  629.         if (event.xany.window == img->win)
  630.         TrackSubWin(img, &histinfo, event.xbutton.x, event.xbutton.y,
  631.             DrawsRect, CropButton, y0);
  632.         else if (event.xany.window == histinfo.his->win)    {
  633.         DrawVMark(histinfo.his, event.xmotion.x, histinfo.his->sub_img);
  634.         histinfo.his->sub_img = clickon = HMARKPOS;
  635.         }break;    /* end of MOVIE_EVENT    */
  636.         case MENU1:    /* case ACTION_OBJECT:    */
  637.         if ((i=WhichImage(event.xany.window, imgp, num_images))>=0 &&
  638.             (i=on_superimpose_elem(imginfo=imgp[i],
  639.                 event.xbutton.x, event.xbutton.y)))
  640.             superimpose_handle(imginfo, i,
  641.                 event.xbutton.x, event.xbutton.y);
  642.         else switch (i=PopingMenu(ctrlmenu, 2, Exposure_handler,
  643.                 imgp, num_images))    {
  644.         case MENU1_INFO:
  645.             Toggle_Info(Help_message_array1);
  646.             break;
  647.         case MENU1_CUT:
  648.             img->update |= img->sub_img;
  649.         case MENU1_COPY:
  650.             if (img->sub_img)
  651.                 CopyOrCutSubImage(img, i==MENU1_CUT);
  652.             else    XBell(img->dpy, 0);
  653.             break;
  654.         case MENU1_CROP:
  655.             sprintf(lbuf, "size: %dH x %dW\ncrop => X0 Y0 height width",
  656.                 img->height, img->width);
  657.             Get_Note_Input(lbuf, sizeof(lbuf), 8, "sub-image ", Yellow, 0);
  658.             sscanf(lbuf, "%d %d %d %d", &img->sub_img_x,
  659.                 &img->sub_img_y,&img->sub_img_h,&img->sub_img_w);
  660.             bound_check(img->sub_img_h, img->sub_img_y, img->height);
  661.             bound_check(img->sub_img_w, img->sub_img_x, img->width);
  662.             img->sub_img = (img->height>4 && img->width>4);
  663.             break;
  664.         case MENU1_DRAW:
  665.             if ((i=PrepareToEdit(imgp, num_images, PaintMesg,
  666.                 lbuf, sizeof(lbuf), &event)) >= 0)
  667.                 DrawInImage(imginfo=imgp[i], &y0, PaintMesg, lbuf);
  668.             break;
  669.         case MENU1_PASTE:
  670.             if (!I_ED.fill)    break;
  671.             DisplayMessage(NoteWin, PasteMesg, 0, 0);
  672.             XMaskEvent(Dpy, ButtonPressMask, &event);
  673.             if ((i=WhichImage(event.xany.window, imgp, num_images))>=0)
  674.             PasteImage(imginfo=imgp[i], &y0);
  675.             break;
  676.         case MENU1_PAINT:
  677.             sprintf(lbuf, "brush size = %d", ps);
  678.             Get_Note_Input(lbuf, sizeof(lbuf), 8, "size ", Green, 0);
  679.             sscanf(lbuf, "%d", &ps);
  680.             if ((i=PrepareToEdit(imgp, num_images, PaintMesg,
  681.                 lbuf, sizeof(lbuf), &event)) >= 0)
  682.                 PaintImage(imginfo=imgp[i], &y0, ps,
  683.                     fnt_r, fnt_g, fnt_b);
  684.             break;
  685.         case MENU1_ANOT:
  686.             if ((i=PrepareToEdit(imgp, num_images, PaintMesg,
  687.                 lbuf, sizeof(lbuf), &event)) >= 0)
  688.                 Annotation(imginfo=imgp[i], &y0, &keysym, &stat);
  689.             break;
  690.         case MENU1_MEAN:
  691. #    ifdef    C_TUNER
  692.             if (img->dpy_channels > 1 && img->sub_img)    {
  693.             byte    *scan[3], *smap[3];
  694.             register int    fact = get_iconsize(img, 0),
  695.                 x = img->sub_img_x, y = img->sub_img_y,
  696.                 iw = img->width;
  697.                 CalcSubWinMean(img->data, img->data, iw,
  698.                 x, y, img->sub_img_w, img->sub_img_h);
  699.                 for (i=img->sub_img_h; i--;)    {
  700.                 scan[0] = ORIG_RLE_ROW(img, y + i) + x;
  701.                 scan[1] = scan[0] + iw;
  702.                 scan[2] = scan[1] + iw;
  703.                 smap[0] = SAVED_RLE_ROW(img, y + i) + x;
  704.                 smap[1] = smap[0] + iw;
  705.                 smap[2] = smap[1] + iw;
  706.                 Map_Scanline(img, scan, smap, x, y + i,
  707.                     img->sub_img_w, fact);
  708.                 }
  709.                 if (img->refresh_pixmap)
  710.                 XPutImage(img->dpy, img->refresh_pixmap,
  711.                     img->gc, img->image, x, y, x, y,
  712.                     img->sub_img_w, img->sub_img_h);
  713.                 handle_exposure(img, Draws, x-img->x0, y-img->y0,
  714.                 img->sub_img_w, img->sub_img_h,
  715.                 img->height, img->update=True);
  716.             }
  717. #    endif
  718.             break;
  719.         case MENU1_SNAP:{
  720.         extern    XColor    qcolor[MaxColors];
  721.         register XImage    *ip;
  722.             Window    win;
  723.             XWindowAttributes    wa;
  724.             register int    j = i = 256;
  725.             XMaskEvent(Dpy, ButtonPressMask, &event);
  726.             win = event.xany.window;
  727.             XGetWindowAttributes(Dpy, win, &wa);
  728.             ip  = XGetImage(Dpy, win, 0, 0, wa.width, wa.height, AllPlanes, ZPixmap);
  729.             img = imgp[num_images++] = zalloc(1, sizeof(*img), "snap");
  730.             init_img_info(img, Dpy, cmn_hd.color_dpy ? RLE : HIPS, cmn_hd.color_dpy);
  731.             img->width = wa.width;    img->height = wa.height;
  732.             img->colormap = wa.colormap;
  733.             img->dpy_channels = img->channels = 1;
  734.             img->color_form = cmn_hd.color_dpy ? CFM_SCF : CFM_SGF;
  735.             img->name = "snap window";
  736.             CreateWindow(img, Monitor, 0, I_Mask | KeyPressMask,
  737.                 0, IconWindowHint | IconPositionHint);
  738.             img->image = ip;
  739.             img->dpy_depth = Monitor[0].dpy_depth;
  740.             img->data = img->scan_data = img->img_buf = ip->data;
  741.             SetImageEvent(img, event);
  742.             XMapWindow(img->dpy, img->frame);
  743.             GetCloseColor(Dpy, wa.colormap, i, 0, 240, 240, 240);
  744.             img->cmaplen = i;
  745.             if (verify_buffer_size(reg_cmap, i * 3, sizeof(cmap_t),
  746.                 "snap_map")) {
  747.                 img->in_cmap = reg_cmap;
  748.                 reg_cmap[1] = reg_cmap[0] + i;
  749.                 reg_cmap[2] = reg_cmap[1] + i;
  750.             }
  751.             while (i--)    {
  752.                 reg_cmap[0][i] = qcolor[i].red >> 8;
  753.                 reg_cmap[1][i] = qcolor[i].green>>8;
  754.                 reg_cmap[2][i] = qcolor[i].blue>>8;
  755.             }
  756. #ifdef    C_TUNER
  757.             if (r_cmap)    free(r_cmap);
  758.             i = img->cmaplen;
  759.             rle_dflt_hdr.cmap = (rle_map*)(r_cmap = (sht_cmap_t*)
  760.                 zalloc(i*(img->ncmap=3), sizeof(*r_cmap), ""));
  761.             rle_dflt_hdr.cmaplen = 8;
  762.             while (i--)    {
  763.                 r_cmap[i] = qcolor[i].red;
  764.                 r_cmap[i + j] = qcolor[i].green;
  765.                 r_cmap[i + (j<<1)] = qcolor[i].blue;
  766.             }
  767. #else
  768.             img->data = nzalloc(i=img->width, img->height);
  769.             for (i *= img->height; i--;)
  770.                 img->data[i] = reg_cmap[0][ip->data[i]];
  771. #endif
  772.             Find_min_max(img, histinfo.histp, img->data, 1, True);
  773.             }
  774.         }    /* end switch(popmenu) */
  775.         HidingPanel(NoteWin);
  776.         break;
  777.         default:    msg("uninstalled event %d\n", mevent);
  778.     }    /* end of switch(mevent) */
  779.     break;    /* end of ButtonPress */
  780.  
  781.     case ButtonRelease:
  782.         if (moved)    {
  783.         switch(clickon)    {
  784.         case NULL:
  785.         case ELALINFO:    /* color() REG color=RGB%channels */
  786.             Fresh_ImageScreen(img, img->cnvt, &new_colors);
  787.             break;
  788.         case CLIPINFO:    topv = ReadSlider(CSlider, 2);
  789.                 top = ReadSlider(CSlider, 1);
  790.             break;
  791.         case QUANINFO:
  792.             if (!quant || ncolors > 64)    break;
  793. #    ifndef    DIRECT
  794.             new_colors = CreateCLT(graylevel, ncolors, DoAll, quant, 1, &histinfo);
  795.             SetColormap(&Monitor[0], graylevel, &new_colors, &newmap, quant);
  796.             MapColor(img, img->cnvt, fsize);
  797.             goto    DrawOthers;
  798. #    endif
  799.         case MOVESCROLLBAR:
  800.             XPutImage(img->dpy, img->win, img->gc, img->image,
  801.             img->x0, img->y0, 0, 0, img->resize_w, img->resize_h);
  802. DrawOthers:        Draw_ImageScrollBars(img);
  803.             if (img->sub_img)    DrawCrop(img, 0, 1);
  804.         }/* end switch */
  805.         moved = False;
  806.         PressButtonState(RstButt)=PressButtonState(rfsButt)=RESETSTATE;
  807.         if (PressButtonState(heqButt) && img->curve!=(ETAHistoEq|ETALinear)){
  808.             PressButtonState(heqButt) = RESETSTATE;
  809.             img->curve &= ~ETAHistoEq;
  810.         }
  811.         DrawPanel(); /* for reset pressbutton */
  812.         HistoHandle(img, &histinfo, HISTO_BACKGROUND);
  813.         }
  814.         else if (img)    /* check for undo loading file and default */
  815.         switch (clickon)    {
  816.         case HMARKPOS:
  817.         case IMAGEINFO:
  818.             if (wp==img->win)    /* for image only */
  819.             XDefineCursor(img->dpy, wp, cursor);
  820.             if (wp != Epanel->win)
  821.             ClearParameterWin(imginfo, y0);
  822.         }
  823.         clickon = 0;
  824.     break;
  825.  
  826.     case KeyPress:    /* color() return *active = -1 */
  827.     {
  828.     char    *str, *XKeysymToString();
  829.     int    len;
  830.     bool    CTRL_Key;
  831.         len = XLookupString(&event, lbuf, sizeof(lbuf), &keysym, &stat);
  832.         lbuf[len] = 0;
  833.         str = XKeysymToString(keysym);    /* useful? */
  834.         CTRL_Key = event.xkey.state & ControlMask;
  835.         if (len == 1) {
  836.             if (*str == 'q' || *str == 'Q') {
  837. MEXIT:            if (!YesOrNo("Quit ?", 0)) {
  838.                 PressButtonState(YesButt) =
  839.                 PressButtonState(NoButt) = RESETSTATE;
  840.                 break;
  841.             }
  842.             if (num_images) {
  843.                 for (i=0; i<num_images; i++) {
  844.                 if (imgp[i]->update)
  845.                     SaveImage(imgp[i]);
  846. #ifdef    C_TUNER
  847.                 DestroyColorImage(imgp[i]);
  848. #else
  849.                 DestroyImage(imgp[i]);
  850. #endif
  851.                 }
  852.             }
  853.             if (newmap)
  854.                 XInstallColormap(Dpy, XDefaultColormap(Dpy, Screen));
  855.             XFreeGC(NoteWin->dpy, NoteWin->gc);
  856.             XDestroyWindow(NoteWin->dpy, NoteWin->win);
  857.             XFreeGC(ctrlmenu->dpy, ctrlmenu->gc);
  858.             XDestroyWindow(ctrlmenu->dpy, ctrlmenu->win);
  859.             XFreeGC(Epanel->dpy, Epanel->gc);
  860.             XDestroyWindow(Epanel->dpy, Epanel->win);
  861.             XCloseDisplay(Dpy);
  862.             if (Dpy1 && Dpy != Dpy1)
  863.                 XCloseDisplay(Dpy1);
  864.             exit(0);
  865.             }
  866.             if (tolower(*str) == 'c') {
  867. #    ifdef    C_TUNER
  868.             if (newmap)
  869.                 XInstallColormap(Dpy, XDefaultColormap(Dpy, Screen));
  870.             XUnmapWindow(Dpy, Epanel->win);
  871.             return    *active = -1;
  872. #    else
  873.             for (i=0; i<num_images; i++)
  874.                 if (imgp[i]->win == event.xany.window){
  875.                 if (imgp[i]->update)
  876.                     SaveImage(imgp[i]);
  877.                 DestroyImage(imgp[i]);
  878.                 while (++i < num_images)
  879.                     imgp[i-1] = imgp[i];
  880.                 imgp[--num_images] = NULL;
  881.                 if (num_images){
  882.                     img = imginfo = imgp[num_images-1];
  883.                     goto    ReSume;/* several lines down */
  884.                 }
  885.                 else    img = NULL;
  886.                 }/* end close image */
  887. #endif
  888.             }
  889.             else if(tolower(*str) == 'h')
  890.             Toggle_Info(Help_message_array1);
  891.         }
  892.     }break;
  893.  
  894.     case EnterNotify:
  895.         if ((i=WhichImage(event.xany.window, imgp, num_images)) >= 0){
  896.         imginfo = imgp[i];
  897.         if (imginfo == img)    break;
  898. ReSume0:    img->active = False;
  899.         img = imginfo;
  900. ReSume:        img->active = True;
  901.         fsize = GetImageBufNSize(img);
  902.         Panel_Image(img, lkt);
  903. #if    defined DIRECT & !defined C_TUNER
  904.         MapColor(img, img->cnvt, fsize, graylevel,
  905.             MAX(VCTEntry, img->marray[img->fn].min));
  906. #endif
  907.         }
  908.         if ((newmap || cca) && (xcrossing->mode != NotifyUngrab)){
  909.         XInstallColormap(Dpy, Monitor[0].cmap);
  910.         XInstallColormap(Dpy1, Monitor[1].cmap);
  911.         }
  912. #    ifdef    _DEBUG_
  913.         else    if (verbose)    mesg("enter notified\n");
  914. #    endif
  915.     break;
  916.  
  917.     case LeaveNotify:
  918.         if((newmap || cca) && (xcrossing->mode != NotifyGrab))
  919.         XInstallColormap(Dpy, XDefaultColormap(Dpy, Screen));
  920. #    ifdef    C_TUNER
  921.         if (!clickon)    {
  922.             *active = 1;
  923.             return    num_images;
  924.         }
  925. #    endif
  926.     break;
  927.  
  928.     case ColormapNotify:
  929. #ifdef    _DEBUG_
  930.     {    static    int    CN=0;
  931.         msg("color change happened %d\r", CN++);
  932.     }
  933. #endif
  934.     break;
  935.  
  936.     case MapNotify:
  937.         if ((i=WhichImage(event.xany.window, imgp, num_images))>=0){
  938.             imginfo = imgp[i];
  939.             if (event.xmap.window == imginfo->win){
  940.                 XUnmapWindow(imginfo->dpy, imginfo->icon);
  941. #ifndef    C_TUNER
  942.                 goto    ReSume0;
  943. #endif
  944.             }
  945.             else if (event.xmap.window == imginfo->icon)
  946.                 XUnmapWindow(imginfo->dpy, imginfo->frame);
  947.         }
  948.         while (XCheckMaskEvent(Dpy, StructureNotifyMask, &event));
  949.     break;
  950.  
  951.     case UnmapNotify:
  952.         if ((i=WhichImage(event.xany.window, imgp, num_images))>=0){
  953.             imginfo = imgp[i];
  954.             if (event.xunmap.window == imginfo->win){
  955.                 if (imginfo->channels == 1)
  956.                     LoadIcon(imginfo);
  957.                 XMapWindow(imginfo->dpy, imginfo->icon);
  958.             }
  959.             else if (event.xunmap.window == imginfo->icon)    {
  960.                 XMapWindow(imginfo->dpy, imginfo->frame);
  961. #ifndef    C_TUNER
  962.                 goto    ReSume0;
  963. #endif
  964.             }
  965.         }
  966.         while (XCheckMaskEvent(Dpy, StructureNotifyMask, &event));
  967.     break;
  968.  
  969.     case ConfigureNotify:    /* any window moving, changing size, ... */
  970.         /* we are only interested in window size change    */
  971.         ResizeWindow(img, &event);
  972.     break;
  973.  
  974.     case MotionNotify:
  975.     switch (clickon)    {
  976.         case ELALINFO:
  977.         SetSBarPos(slider, event.xbutton.x, event.xbutton.y, sb);
  978.         moved++;
  979.         break;
  980.         case CLIPINFO:
  981.         SetSBarPos(CSlider, event.xbutton.x, event.xbutton.y,sb);
  982.         moved++;
  983.         break;
  984.         case QUANINFO:
  985.         SetSBarPos(QSlider, event.xbutton.x, event.xbutton.y,sb);
  986.         moved++;
  987.         break;
  988.         case MOVESCROLLBAR:
  989.         SetScrollBar(img->parts, event.xbutton.x, event.xbutton.y, sb-1);
  990.         moved++;
  991.         break;
  992.         case HMARKPOS:
  993.         DrawVMark(histinfo.his, event.xmotion.x, True);
  994.         case IMAGEINFO:
  995.         ParameterWin(imginfo, &histinfo, event.xbutton.x, event.xbutton.y,
  996.                 y0, wp==histinfo.his->win);
  997.         /* end of IMAGEINFO */
  998.     }break;    /* end of clickon */
  999.     default:    if (verbose)
  1000.         msg("%d Not a Panel Event\n", event.type);
  1001.     }
  1002.     }    /* end while */
  1003. }    /* End of Tuner */
  1004.  
  1005. void
  1006. SetImageEvent(img, event)
  1007. Image    *img;
  1008. XEvent    *event;
  1009. {
  1010.     img->event = event;
  1011.     img->color_dpy = cmn_hd.color_dpy;
  1012.     img->hist = nzalloc(HistoSize*3, sizeof(*(img->hist)), "hist");
  1013. }
  1014.  
  1015. void
  1016. Panel_Image(img, lkt)
  1017. Image    *img;
  1018. LKT    *lkt;
  1019. {
  1020.     SetSBarRPos(LSlider, img->linearlow, 1);
  1021.     SetSBarRPos(LSlider, img->linearup, 2);
  1022.     SetSBarRPos(ESlider, img->bgrd, 1);
  1023.     ChangeSliderScale(ESlider, img->scale, ESlider==slider);
  1024.     ChangeSlider(img, &slider, ESlider, LSlider, heqButt, EButton);
  1025. /*    ButtonState(maxButt of hButton) = img->setscale;    */
  1026. #ifdef    C_TUNER
  1027.     ButtonState(fButton) = img->fn;
  1028.     ChangePanelCmap(img);
  1029. #else
  1030.     SetShowFramePos(img, fButton, 0);
  1031. #endif
  1032.     DrawPanel();
  1033.     PanelMessage(FButton, img->name, 0, 0, 0);
  1034.     histinfo.histp = img->hist;    /* point to image histogram */
  1035. #ifndef    DIRECT
  1036.     if (histinfo.map || img->frames==1)
  1037. #endif
  1038.         new_curve(lkt, &histinfo, img->marray, img->curve, 0,
  1039.             img, img->width*img->height);
  1040.     HistoHandle(img, &histinfo, HISTO_BACKGROUND);
  1041. }
  1042.  
  1043. void
  1044. Fresh_ImageScreen(img, rp, new_colors)
  1045. Image    *img;
  1046. byte    *rp;
  1047. int    *new_colors;
  1048. {
  1049. int    map_flag = 1;
  1050. register byte    *mtmp = rp;    /* here, rp is for interpolation only */
  1051. register int    i;
  1052.     img->linearlow = ReadSlider(LSlider, 1);
  1053.     img->linearup = ReadSlider(LSlider, 2);
  1054.     if (img->curve == ETABackGD)
  1055.         img->bgrd = ReadSlider(ESlider, 1);
  1056.     if (img->curve == ETAForeGD)
  1057.         img->fgrd = ReadSlider(ESlider, 1);
  1058. #ifdef    C_TUNER
  1059.     i = img->fn % 3;
  1060.     cer[i].lower = img->linearlow;
  1061.     cer[i].upper = img->linearup;
  1062.     cer[i].bgrd = img->bgrd;
  1063.     cer[i].fgrd = img->fgrd;
  1064. #endif
  1065.     if (PressButtonState(RstButt) || ButtonState(Interpolate))
  1066.     {
  1067.         ResetLKT(lkt, img);
  1068.         if (ButtonState(Interpolate)){
  1069.         sprintf(lbuf, "Interpolate %s[f%d]", img->name, img->fn);
  1070.         DispInfo(Epanel, 0, lbuf, white1);
  1071. #ifdef    C_TUNER
  1072.         if (img->channels > 1)
  1073.         {    memcpy(&cmn_hd, img, sizeof(cmn_hd));
  1074.             row *= img->channels;
  1075.             interpolation(img->data, img->scan_data,
  1076.             x_regions, y_regions, IM, &cmn_hd, &histinfo);
  1077.         } else
  1078. #endif
  1079.         interpolation(rp, mtmp=(VType*)img->image->data,
  1080.             x_regions, y_regions, IM, img, &histinfo);
  1081.         Find_min_max(img, histinfo.histp, mtmp, Yes, False);
  1082.         }
  1083.     }
  1084.     else new_curve(lkt, &histinfo, img->marray + (img->color_dpy ?
  1085.         img->fn%img->channels : (img->frames > 1 ? img->fn : 0)),
  1086.         img->curve, 0, img, img->width*img->height);
  1087.     if (img->color_dpy && img->fn == ButtonSync)    {
  1088.         cer[2] = cer[1] = cer[0];
  1089.         for (i=1; i<3; i++)
  1090.         memcpy(lkt+MaxColors*i, lkt, sizeof(*lkt)*MaxColors);
  1091.     }
  1092. #ifdef    DIRECT
  1093. #    ifdef    C_TUNER
  1094.     map_flag = img->dpy_depth < 24 &&
  1095.             ((image_information*)img)->visual_class < TrueColor;
  1096.     if(cer[0].intp || ButtonState(Interpolate) || !map_flag)    {
  1097.         eta_scan_map(img, ButtonState(Interpolate));
  1098.         mtmp = PrtCAST img->image->data;
  1099.         if (!map_flag)    {
  1100.         register LKT    *lktr=lkt, *lktg=lktr+MaxColors, *lktb=lktg+MaxColors;
  1101.           if (ImageByteOrder(img->dpy) != LSBFirst)
  1102.             for (i=img->image->bytes_per_line*img->height>>2; i--;) {
  1103.             mtmp++;
  1104.             *mtmp++ = lktb[*mtmp];
  1105.             *mtmp++ = lktg[*mtmp];
  1106.             *mtmp++ = lktr[*mtmp];
  1107.             }
  1108.           else for (i=img->image->bytes_per_line*img->height>>2; i--;){
  1109.             *mtmp++ = lktr[*mtmp];
  1110.             *mtmp++ = lktg[*mtmp];
  1111.             *mtmp++ = lktb[*mtmp];
  1112.             mtmp++;
  1113.             }
  1114.         }
  1115.         histogram(img->data, img->width*img->height, histinfo.histp, img);
  1116.         cer[0].intp = 0;
  1117.         Put_Image(img);
  1118.         ImageBackup(img);
  1119.     }
  1120. #    endif    C_TUNER
  1121.     if (map_flag)
  1122.         MapColor(img, mtmp, fsize, graylevel,
  1123.         MAX(VCTEntry, img->marray[img->fn].min));
  1124. #else
  1125.     if (quant && img->curve==ETALinear)    {
  1126.         *new_colors = CreateCLT(graylevel, ncolors, DoAll, quant, 1, &histinfo);
  1127.         SetColormap(&Monitor[0], graylevel, new_colors, &newmap, quant);
  1128.     }
  1129.     MapColor(img, mtmp, fsize);
  1130.     Draw_ImageScrollBars(img);
  1131.     if (img->sub_img)
  1132.         DrawCrop(img, 0, 1);
  1133. #endif
  1134. }
  1135.  
  1136. Update_ImageData(img, lbuf)
  1137. Image    *img;
  1138. VType    *lbuf;
  1139. {
  1140. int    i;
  1141.     sprintf(lbuf, "Update %s[f%d]", img->name, img->fn);
  1142.     DispInfo(Epanel, 0, lbuf, white1);
  1143.     img->update = True;
  1144.     (*img->std_swif)(FI_DESC_ETA, img, lbuf, cer);
  1145. #ifdef    C_TUNER    /* update RGB image only */
  1146.     if (img->dpy_channels > 1)    {
  1147.     register int    j, ch, *lktp;
  1148.     byte    *pp[3], *dp[3];
  1149.     int    my,
  1150.         s_w = img->sub_img ? img->sub_img_w : img->width,
  1151.         s_h = img->sub_img ? img->sub_img_h : img->height,
  1152.         X0 = img->sub_img ? img->sub_img_x : 0,
  1153.         Y0 = img->sub_img ? img->sub_img_y : 0,
  1154.         icon_factor = get_iconsize(img, 0);
  1155.         for (i=0; i<s_h; i++)    {
  1156.         my = Y0 + s_h - i - 1;
  1157.         pp[0] = ORIG_RLE_ROW(img, my);
  1158.         pp[1] = pp[0] + img->width;
  1159.         pp[2] = pp[1] + img->width;
  1160.         dp[0] = SAVED_RLE_ROW(img, my);
  1161.         dp[1] = dp[0] + img->width;
  1162.         dp[2] = dp[1] + img->width;
  1163.         for (ch=0; ch<img->dpy_channels; ch++)    {
  1164.         register int    min = img->marray[ch].min;
  1165.             lktp = lkt + ch*MaxColors;
  1166.             for (j=X0; j<s_w+X0; j++)
  1167.             pp[ch][j] = lktp[pp[ch][j] - min];
  1168.         }
  1169.         MapRGB(0, 0, &img, pp, dp, my, img->width,
  1170.             my, icon_factor);
  1171.         }
  1172.         histogram(img->data, img->width*img->height, histinfo.histp, img);
  1173.         Put_Image(img);    ImageBackup(img);
  1174.     }
  1175.     else
  1176. #endif
  1177.     if (ButtonState(Interpolate))
  1178.         interpolation(img->cnvt, img->cnvt, x_regions, y_regions,
  1179.         IM, img, &histinfo);
  1180.     else    {
  1181.     register byte    *bp = img->cnvt;
  1182.     register int    min = img->mmm.min;
  1183.         if (img->sub_img){
  1184.         register int    j;
  1185.         bp += img->sub_img_y * img->width + img->sub_img_x;
  1186.         for (i=0; i<img->sub_img_h; i++){
  1187.             for (j=0; j<img->sub_img_w; j++)
  1188.             bp[j] = lkt[bp[j] - min];
  1189.             bp += img->width;
  1190.         }
  1191.         }
  1192.         else for (i=fsize; i--;)
  1193.             bp[i] = lkt[bp[i] - min];
  1194.     }
  1195.     if (verbose)    sleep(2);
  1196.     ButtonState(EButton) = ETALinear;
  1197.     ButtonState(DButton) = RESETSTATE;
  1198.     DrawButton(DButton);
  1199. }
  1200.  
  1201. void
  1202. PasteImage(img, y0)
  1203. Image    *img;
  1204. int    *y0;
  1205. {
  1206.     TopWindow(img, img->sub_img=0);
  1207.     /* handle exposure generated from TopWindow 1st.    */
  1208.     do    {
  1209.         Exposure_handler(img->event, img);
  1210.         XFlush(img->dpy);
  1211.     } while (ImageEvent(img, ExposureMask));
  1212.     memcpy(I_ED.copy, img, sizeof(Image));
  1213.     XDefineCursor(img->dpy, img->win, 0);
  1214.     I_ED.copy->sub_img_w = I_ED.w;
  1215.     I_ED.copy->sub_img_h = I_ED.h;
  1216.     while (!ImageEvent(img, ButtonReleaseMask))
  1217.     if (ImageEvent(img, PointerMotionMask))    {
  1218.     register int    yo;
  1219.         if (I_ED.copy->sub_img)
  1220.             DrawCrop(I_ED.copy, 0, 1);
  1221.         I_ED.dstx = I_ED.copy->sub_img_x = img->event->xbutton.x + img->x0;
  1222.         I_ED.dsty = I_ED.copy->sub_img_y = img->event->xbutton.y + img->y0;
  1223.         yo = SetParameterWin(img, img->event, img->font_h, 0);
  1224.         if (yo != *y0) {
  1225.             ClearParameterWin(img, *y0=yo);
  1226.             while (ImageEvent(img, ExposureMask))
  1227.                 Exposure_handler(img->event, img);
  1228.         }
  1229.         ParameterWin(img, &histinfo, I_ED.dstx, I_ED.dsty, yo, 0);
  1230.         I_ED.copy->sub_img = DrawCrop(I_ED.copy, 0, 1);
  1231.     }
  1232.     {
  1233.     register int    i, Isize = img->width * img->height,
  1234.             w = MIN(I_ED.w, img->width - I_ED.dstx),
  1235.             h = MIN(I_ED.h, img->height - I_ED.dsty);
  1236.     byte* cpbuf = (img->data + (img->color_dpy || img->frames<2
  1237.             ? 0 : img->fn * Isize) ),
  1238.         *src_area = (I_ED.src->channels < img->channels) ? (byte*)
  1239.             map_1_to_3(I_ED.copyarea, NULL, I_ED.src->in_cmap,
  1240.                 I_ED.w, I_ED.h) : (byte*)I_ED.copyarea;
  1241.         if (img && w>0 && h>0 && I_ED.dstx>=0 && I_ED.dsty>=0)    {
  1242.         {
  1243.         register byte    *srcp = src_area, *cp = cpbuf + I_ED.dstx +
  1244.                 I_ED.dsty*img->width*img->channels;
  1245.         register int    factors=I_ED.src->channels/img->channels;
  1246.         if (factors)    factors--;    /* color quant will be here */
  1247.         i = MAX(MaxColors, I_ED.src->cmaplen);    /* tricky of buildmap */
  1248.             if (I_ED.src != img && img->dpy_channels == 1 &&
  1249.             I_ED.src->dpy_channels == img->dpy_channels &&
  1250.                 I_ED.src->color_dpy) {
  1251.             cmap_t    transf[MaxColors];
  1252.             register cmap_t    *cr=I_ED.src->in_cmap[0], *cg=cr+i, *cb=cg+i;
  1253.             for (i=I_ED.src->cmaplen; i--;)
  1254.                 transf[i] = CloseColor_in_Map(img->in_cmap,
  1255.                     img->cmaplen, cr[i], cg[i], cb[i], 384);
  1256.             for (i=I_ED.w * I_ED.h; i--;)
  1257.                 srcp[i] = transf[srcp[i]];
  1258.             }
  1259.             for (i=h; i--; srcp += I_ED.w*factors)    {
  1260.             register int    chan = img->channels;
  1261.                 while (chan--)
  1262.                 memcpy(cp, srcp, w),
  1263.                 srcp += I_ED.w,
  1264.                 cp += img->width;
  1265.             }
  1266.         }
  1267.         if (src_area != (byte*)I_ED.copyarea)
  1268.             free(src_area);
  1269.         I_ED.dst = img;
  1270.         img->sub_img_x = I_ED.dstx;
  1271.         img->sub_img_y = I_ED.dsty;
  1272.         img->sub_img_w = w;
  1273.         img->sub_img_h = h;
  1274.         img->update = True;
  1275. #    ifndef    C_TUNER
  1276.         XClearArea(img->dpy, img->win,
  1277.             I_ED.dstx, I_ED.dsty, I_ED.w, I_ED.h, 1);
  1278. #    endif
  1279. #    ifndef    DIRECT
  1280.         Find_min_max(img, histinfo.histp, cpbuf, Yes, True);
  1281. #    endif
  1282. #    ifndef    DIRECT
  1283.         ResetORange(img);
  1284.         ResetLKT(lkt, img);
  1285.         MapColor(img, cpbuf, Isize);
  1286. #    elif    C_TUNER
  1287.         {
  1288.         byte    *scan_line[3], *dp[3];
  1289.         register int    l, my, icon_factor=get_iconsize(img, 0);
  1290.             for (l=0; l<h; l++)    {
  1291.             my = I_ED.dsty + l - 1;
  1292.             scan_line[0] = ORIG_RLE_ROW(img, my);
  1293.             dp[0] = SAVED_RLE_ROW(img, my);
  1294.             for (i=1; i<img->channels; i++)
  1295.                 scan_line[i] = scan_line[i-1] + I_ED.dst->width,
  1296.                 dp[i] = dp[i-1] + I_ED.dst->width;
  1297.             MapRGB(0, NULL, &img, scan_line, dp,
  1298.                 my, I_ED.dst->width, my, icon_factor);
  1299.             }
  1300.         }
  1301.         PlaceArea(img, I_ED.dstx, I_ED.dsty, I_ED.w, I_ED.h);
  1302. #    endif
  1303.         }    /* end if */    else    DrawCrop(I_ED.copy, 0, 1);
  1304.     }    /* end section */
  1305. Find_min_max(img, histinfo.histp=img->hist, img->data, Yes, True);
  1306. }
  1307.  
  1308. void
  1309. PaintImage(img, y0, s, r, g, b)
  1310. Image    *img;
  1311. int    *y0;
  1312. {
  1313. int    wh, d = img->sub_img_w = img->sub_img_h = (s<<1) + 1,
  1314.     gs = AdoptColor(img, r, g, b, precision);
  1315.  
  1316.     while (1) {
  1317.     wh = WaitButtonPress_n_InfoImage(img, &histinfo, y0,
  1318.         XCreateFontCursor(img->dpy, XC_crosshair));
  1319.     RemoveImageEvent(img, ButtonAction)    XBell(img->dpy, 0);
  1320.     if (wh == Button3)    break;
  1321.     if (wh == Button2)    {
  1322.         gs = PickUpColor(img, &r, &g, &b);
  1323.         continue;
  1324.     }
  1325.     XDefineCursor(img->dpy, img->win, XCreateFontCursor(img->dpy, XC_pencil));
  1326.     img->update = True;
  1327.     while (!ImageEvent(img, ButtonReleaseMask))
  1328.         if (ImageEvent(img, PointerMotionMask))
  1329.         PaintArea(img, img->cnvt, img->event->xbutton.x,
  1330.             img->event->xbutton.y, r, g, b, gs, s);
  1331.     }    /* end while (1) */
  1332. }
  1333.  
  1334. CopyOrCutSubImage(img, ed_cut)
  1335. Image    *img;
  1336. {
  1337.  
  1338.     I_ED.x0 = img->sub_img_x;
  1339.     I_ED.y0 = img->sub_img_y;
  1340.     I_ED.w = img->sub_img_w;
  1341.     I_ED.h = img->sub_img_h;
  1342.     if (I_ED.copyarea)
  1343.         free(I_ED.copyarea);
  1344.     I_ED.copyarea = nzalloc(I_ED.w * I_ED.h, img->channels, "I_ED.copy");
  1345.     {
  1346.     register byte*    cp = I_ED.copyarea,
  1347.         *srcp = img->cnvt + img->channels*img->width*I_ED.y0 + I_ED.x0;
  1348.     register int    i;
  1349.         for (i=I_ED.h*img->channels; i--;) {
  1350.             memcpy(cp, srcp, I_ED.w);
  1351.             cp += I_ED.w;
  1352.             srcp += img->width;
  1353.         }
  1354.         if (I_ED.cut = ed_cut)    { /* using paint is slow but easy */
  1355.         int    r, g, b=BackGD;
  1356.             if (img->in_cmap)    {
  1357.                 r = img->in_cmap[0][b];
  1358.                 g = img->in_cmap[1][b];
  1359.                 b = img->in_cmap[2][b];
  1360.             } else    r = g = b;
  1361.         PaintArea(img, img->data, I_ED.x0-img->x0, I_ED.y0-img->y0,
  1362.             r, g, b, BackGD, 0);
  1363.         }
  1364.         I_ED.fill = True;
  1365.         I_ED.src = img;
  1366.     }
  1367. }
  1368.  
  1369. PrepareToEdit(imgp, num_imgs, msg, lbuf, size, event)
  1370. Image**    imgp;
  1371. XEvent*    event;
  1372. char*    msg, *lbuf;
  1373. {
  1374.     sprintf(lbuf, "R=%d, G=%d, B=%d", fnt_r, fnt_g, fnt_b);
  1375.     Get_Note_Input(lbuf, size, 8, "R, G, B ", Green, 0);
  1376.     sscanf(lbuf, "%d %d %d", &fnt_r, &fnt_g, &fnt_b);
  1377.     DisplayMessage(NoteWin, msg, 4, 0);
  1378.     XMaskEvent(Dpy, ButtonPressMask, event);
  1379. return    WhichImage(event->xany.window, imgp, num_imgs);
  1380. }
  1381.  
  1382. PaintArea(img, rp, x, y, r, g, b, gs, err)
  1383. Image    *img;
  1384. byte    *rp;
  1385. {
  1386. byte    *scan[3];
  1387. register int    dy=img->sub_img_h, dx=img->sub_img_w, rt_x, rt_y;
  1388. img->sub_img_x = (x += img->x0 - err);
  1389. img->sub_img_y = (y += img->y0 - err);    err <<= 1;
  1390.  
  1391.  
  1392.     if (x >= 0 && x < img->width-err && y >= 0 && y < img->height-err)
  1393.     for (rt_y=y+dy; rt_y-- > y;)    {
  1394.     byte    *p[3];
  1395.     err = rt_y*img->width*img->channels + x;
  1396.     p[0] = rp + err;
  1397.     p[1] = p[0] + img->width;
  1398.     p[2] = p[1] + img->width;
  1399.         for (rt_x=dx; rt_x--;) {
  1400.         if (img->channels == 1)
  1401.             p[0][rt_x] = gs;
  1402.         else    {
  1403.             p[0][rt_x] = r;
  1404.             p[1][rt_x] = g;
  1405.             p[2][rt_x] = b;
  1406.         }
  1407.         }
  1408. #    ifdef    C_TUNER
  1409.         scan[0] = img->scan_data + err;
  1410.         scan[1] = scan[0] + img->width;
  1411.         scan[2] = scan[1] + img->width;
  1412.         Map_Scanline(img, p, scan, x, rt_y, dx, get_iconsize(img, 0));
  1413. #    endif
  1414.     }
  1415. #    ifndef    C_TUNER
  1416.     img->sub_img++;
  1417.     MapColor(img, rp, img->width * img->height);
  1418. #    endif
  1419.     PlaceArea(img, x, y, dx, dy);
  1420. img->sub_img = 0;
  1421. }
  1422.  
  1423. PlaceArea(img, x, y, dx, dy)
  1424. register Image    *img;
  1425. register x, y, dx, dy;
  1426. {
  1427. register int    x0=x, y0=y;
  1428. #ifndef    SCROLLBAR_on_CANVAS
  1429.     x -= img->x0,    y -= img->y0;
  1430. #endif
  1431.     XPutImage(img->dpy, img->win, img->gc, img->image,
  1432.             x0, y0, x, y, dx, dy);
  1433. #    ifdef    C_TUNER
  1434.     if (img->refresh_pixmap)
  1435.         XCopyArea(img->dpy, img->win, img->refresh_pixmap,
  1436.             img->gc, x, y, dx, dy, x0, y0);
  1437. #    endif
  1438. }
  1439.  
  1440.